#pragma once
#include<iostream>
#include<pthread.h>
#include<sys/socket.h>
#include<cstdlib>
#include<stdio.h>
#include<signal.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include<cstring>
#define PORT 8080
#define BACKLOG 5
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;//设置一把全局锁；

enum
{
    //一些错误码；
    SOCKERR = 1,
    BINDERR,
    LISTENERR,
};

class Tcpservice
{
public:
    static Tcpservice*getTcpservice(int port)
    {
        if(_tcp == nullptr)//提高效率；
        {
            pthread_mutex_lock(&mutex);//多线程竞争锁；
            if(_tcp == nullptr)
            {
                _tcp = new Tcpservice(port);
                _tcp->Init();
            }
            pthread_mutex_unlock(&mutex);
        }
        return _tcp;
    }
    int Sock()
    {
        return _listensock;
    }
private:
    void Init()
    {
        signal(SIGPIPE,SIG_IGN);
        signal(SIGSEGV,SIG_IGN);
        //1.create socket;
        Socket();
        //2.bind socket;
        Bind();
        //3.listen socket;
        Listen();
    }
    void Socket()
    {
        _listensock = socket(AF_INET,SOCK_STREAM,0);
        if(_listensock<0)
        {
            perror("socket");
            exit(SOCKERR);
        }
        //display log;
        int opt = 1;
        setsockopt(_listensock, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    }
    void Bind()
    {
        struct sockaddr_in local;
        memset(&local,0,sizeof(local));//初始化local字段；
        local.sin_family = AF_INET;
        local.sin_port = htons(_port);
        local.sin_addr.s_addr = 0;
        int n = bind(_listensock,(const struct sockaddr*)&local,sizeof(local));
        if(n<0)
        {
            perror("bind");
            exit(BINDERR);
        }
    }
    void Listen()
    {
        int n = listen(_listensock,BACKLOG);

        if(n<0)
        {
            perror("listen");
            exit(LISTENERR);
        }
    }
private:
//将这个类设置成懒汉单例模式；
        Tcpservice(int port = PORT)
        :_port(port)
        ,_listensock(-1)
        {}
        Tcpservice&operator=(Tcpservice&tcp)=delete;
        Tcpservice(const Tcpservice&tcp)=delete;

private:
    int _listensock;
    u_int16_t _port;
    static Tcpservice*_tcp;
    static int a;
};

 Tcpservice*Tcpservice::_tcp = nullptr;//静态成员变量类内声明，类外定义；
